package com.climber.android.commonsdk.api

import com.climber.android.commonsdk.api.entity.APIResponse
import com.climber.android.commonsdk.api.entity.TOKEN_EXPIRED
import com.climber.android.commonsdk.api.entity.URL_NEED_TOKEN
import com.climber.android.commonsdk.event.BusProvider
import com.climber.android.commonsdk.event.CommonBusEvent
import com.climber.android.commonsdk.util.APIDataHelper
import io.ganguo.library.klog.KLog
import io.ganguo.library.mvp.util.MainLooper
import io.ganguo.library.mvp.util.NetworkUtils
import io.library.android.rxweaver.core.GlobalErrorTransformer
import io.library.android.rxweaver.retry.RetryConfig
import io.reactivex.Observable
import io.reactivex.Single
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException

object GlobalErrorProcessor {
    @JvmStatic
    fun <T> processGlobalError(noticeErrorInfo: Boolean = true):
            GlobalErrorTransformer<T> = GlobalErrorTransformer(
            // 通过onNext流中数据的状态进行操作
            onNextInterceptor = {rawResponse ->
                val result = rawResponse
                if(result is APIResponse){
                    if(result.isSuccessful()){
                        Observable.just(rawResponse)
                    } else{
                        Observable.error(APIError.ServerError(errorCode = result.getServerErrorCode(), errorMsg = result.getServerErrorMsg()))
                    }
                } else{
                    Observable.just(rawResponse)
                }
            },

            // 通过onError中Throwable状态进行操作
            onErrorResumeNext = { error ->
                when (error) {
                    is HttpException -> {
                        var errorMsg = ""
                        when(error.code()){
                            400 -> errorMsg = "请求参数错误，请检查请求参数是否正确"
                            404 -> errorMsg = "服务器找不到请求页面（页面已被移除）"
                            416 -> errorMsg = "请求Http数据流范围错误"
                            500,502,504 -> errorMsg = "服务器错误，请稍后重试"
                            415 -> errorMsg = "不支持的请求类型"
                            else -> {
                                error.response()?.errorBody()?.let {
                                    errorMsg = it.string()
                                }
                            }
                        }
                        Observable.error<T>(APIError.ServerError(errorCode = error.code(), errorMsg = errorMsg))
                    }
                    is ConnectException, is SocketTimeoutException ->
                        Observable.error<T>(APIError.ConnectFailedException(error))
                    else -> Observable.error<T>(error)
                }
            },

            onErrorRetrySupplier = { retrySupplierError ->
                when (retrySupplierError) {
                    //server error， 不重试
                    is APIError.ServerError -> {
                        RetryConfig.none()
                    }
                    // 网络连接异常，默认重试1次
                    is APIError.ConnectFailedException ->{
                        RetryConfig.simpleInstance {
                            if(!NetworkUtils.isNetworkConnected()){
                                Single.just(false)
                            } else{
                                Single.just(true)
                            }
                        }
                    }
                    else -> RetryConfig.none()      // 其它异常都不重试
                }
            },

            onErrorConsumer = { error ->
                MainLooper.runOnUiThread {
                    when (error) {
                        is APIError.ServerError -> {
                            when {
                                error.errorCode == URL_NEED_TOKEN ->{
                                    // 需要登录携带toke才可以访问API
                                    BusProvider.getInstance().post(CommonBusEvent.NeedTokenEvent())
                                }
                                error.errorCode == TOKEN_EXPIRED ->{
                                    // token 过期， 需要重新登录
                                    BusProvider.getInstance().post(CommonBusEvent.TokenExpiredEvent())
                                }
                                noticeErrorInfo -> APIDataHelper.showAPIError(error)
                            }
                        }
                        else -> KLog.w("rx stream Exception", "其它异常:${error.message}")
                    }
                }
            }
    )
}